package com.gitee.btssplib

import android.util.Log
import io.reactivex.BackpressureStrategy
import io.reactivex.Flowable
import io.reactivex.FlowableEmitter
import io.reactivex.FlowableOnSubscribe
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.atomic.AtomicLong

class BTSender(private val connector: BTConnector, private val sendListener: SendListener) {

    companion object {
        const val TAG = "BTSender"
    }

    enum class State {
        IDLE, // 空闲
        SENDERING, // 正在发送数据
        SEND_ERROR // 发送数据发生错误
    }

    // 发送包
    class SendPackage(val id: Long, val buffer: ByteArray) {}

    var sendId: AtomicLong = AtomicLong() // 发送ID
    var state: State = State.IDLE // 发送器状态
    var bufferEmitter: FlowableEmitter<SendPackage>? = null // 缓存发射器，用于发射外部传入的数据
    private var sendThread: Disposable? = null // 读数据线程

    private fun start() {
        sendThread = Flowable.create(FlowableOnSubscribe<SendPackage> { emitter ->
            bufferEmitter = emitter
        }, BackpressureStrategy.BUFFER)
                .observeOn(Schedulers.io())
                .subscribe { sendPackage ->
                    try {
                        state = State.SENDERING
                        connector.bluetoothSocket?.outputStream?.write(sendPackage.buffer)
                        Flowable.just(sendPackage)
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe { packageBack ->
                                    Log.d(TAG, "发送数据成功:${packageBack.id}")
                                    sendListener.onSuccess(packageBack.id, packageBack.buffer)
                                }
                    } catch (e: Exception) {
                        e.printStackTrace()
                        state = State.SEND_ERROR
                        Log.d(TAG, "发送数据失败:${sendPackage.id}")
                        sendListener.onError(e)
                    }
                }
    }

    // 发送数据，返回发送的id
    @Synchronized
    fun send(buffer: ByteArray): Long {
        if (bufferEmitter == null) {
            Log.d(TAG, "数据发送器未启动，现在启动")
            start()
            Log.d(TAG, "数据发送器启动成功")
        }
        val sendId = sendId.incrementAndGet()
        bufferEmitter?.onNext(SendPackage(sendId, buffer))
        return sendId
    }

    @Synchronized
    fun stop() {
        if (sendThread != null) {
            Log.d(TAG, "正在停止发送器")
            try {
                sendThread?.dispose()
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                bufferEmitter = null
                sendThread = null
                state = State.IDLE
            }
        }
    }
}